<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>拼图游戏</title>
<!--    css文件引入-->
    <link rel="stylesheet" href="./css/main.css">

</head>
<body>
    <div class="game" id="game">
        <div class="float">
            <div class="game-example">
                <img src="images/game-bg.jpg" >
            </div>
        </div>
        <div class="game-content" id="app">
            <div class="btn" @click="init">Reset</div>
            <span style="border: 1px solid;margin-bottom: 10px;display: inline-block;padding: 10px 20px; border-radius: 5px;">步数:{{total}}</span>
            <div class="container" :key="total">
                <div v-for="(v,k) in gameElement" :id="'el-'+k" @click="swap(k)" :class="v==null?'game-el null':'game-el'" :style="{left:(k%3)*33.3+'%',top: Math.floor(k/3)*33.3+'%','background-position-x':((v-1)%3)*38.3+`%`,'background-position-y':Math.floor((v-1)/3) * 49.3+`%`}"></div>
            </div>
        </div>

    </div>
    <img src="images/上下左右.png" alt="baba" class="img-move">
</body>
<script src="./js/main.js"></script>
<script src="./js/vue.min.js"></script>
<script src="./js/jquery.js"></script>

<script>
    var app = new Vue({
        el: "#app",
        data: {
            moveFlag: true,
            nullIndex: 7,
            total: 0,
            gameElement: [
                1,2,3,
                4,5,6,
                7,null,8
            ],
            initNull: 8
        },
        methods: {
            isNull(index){
                return index >= 0 && index < this.gameElement.length && Object.assign(this.gameElement)[index] == null
            },
            inArea(index){
                if (this.isNull(index + 3)){
                    return true
                }
                if (this.isNull(index - 3)){
                    return true
                }
                if (this.isNull(index + 1)){
                    return true
                }
                if (this.isNull(index - 1)){
                    return true
                }
                return false
            },
            swap(index){
                if (!this.moveFlag){
                    return;
                }
                if (!this.inArea(index)){
                    return;
                }
                let nullIndex = Object.assign(this.nullIndex)
                let css = {
                    left:(nullIndex%3)*33.3+'%',top: Math.floor(nullIndex/3)*33.3+'%'
                }
                new Promise(resolve => {
                    this.moveFlag = false
                    $(`#el-${index}`).css(css)
                    setTimeout(function (){
                        resolve()
                    },200)
                }).then(e=>{
                    this.moveFlag = true
                    let temp = Object.assign(this.gameElement[index])
                    let nullIndex = Object.assign(this.nullIndex)
                    this.gameElement[index] = null
                    this.gameElement[nullIndex] = temp
                    this.nullIndex = index
                    this.total ++
                    this.isWin()
                })

            },
            move(index,moveIndex){
                if (this.isNull(index)){
                    this.swap(moveIndex)
                }
            },
            contain(x, y) {
                return Math.floor(x/3) == Math.floor(y/3)
            },
            isWin(){
                let flag = true
                for (let i = 0;i < this.gameElement.length - 1;i ++){
                    if (i != this.gameElement[i] - 1){
                        flag = false
                    }
                }
                if (flag){
                    new Promise((resolve)=>{
                        this.gameElement[this.nullIndex] = 9

                        setTimeout(()=>{
                            resolve()
                        },0)
                    }).then(()=>{
                        alert("结束了，分数为" + this.total)

                    })
                }
            },
            init(){
                this.initNull = 8
                this.total = 0
                this.gameElement = this.random()
            },
            random(){
                let map = [1,2,3,4,5,6,7,8,null]
                map = this.random_move(map)
                map.forEach((value,index) => {
                    if (value == null){
                        this.nullIndex = index
                    }
                })
                return map
            },
            random_move(arr){
                for (let i =0;i < 100;i ++){
                    arr = this.random_position(arr,this.getRandomIntInclusive(0,3))
                }
                return arr
            },
            random_position(arr,position){
                switch (position){
                    case 0:
                        if (this.contain(this.initNull,this.initNull + 1)){
                            return this.random_swap(arr,this.initNull + 1)
                        }
                        return arr
                    case 1:
                        if (this.contain(this.initNull,this.initNull - 1)){
                            return this.random_swap(arr,this.initNull - 1)
                        }
                        return arr
                    case 2:
                        return this.random_swap(arr,this.initNull - 3)
                    case 3:
                        return this.random_swap(arr,this.initNull + 3)
                }
            },
            random_swap(arr,index){
                if (this.random_isNull(arr,index)){
                    return this.random_position(arr,this.getRandomIntInclusive(0,3));
                }
                let temp = arr[index]
                arr[index] = null
                arr[Object.assign(this.initNull)] = temp
                this.initNull = index
                return arr
            },
            random_isNull(arr,index){
                return index < 0 || index >= arr.length
            },
            getRandomIntInclusive(min, max) {
                min = Math.ceil(min);
                max = Math.floor(max);
                return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值，含最小值
            }
        },
        updated(){
            $('.container').height($('.container').width() * ($(".game-example").height() / $('.game-example').width())+4)

        },

        mounted(){
            $('.container').height($('.container').width() * ($(".game-example").height() / $('.game-example').width()) +4)
            $(window).on('keydown',e=>{
                if (e.key == "ArrowUp"){
                    let i = this.nullIndex
                    this.move(i,i+3)
                }
                if (e.key == "ArrowDown"){
                    let i = this.nullIndex
                    this.move(i,i-3)
                }
                if (e.key == "ArrowLeft"){
                    let i = this.nullIndex
                    if (!this.contain(i,i+1)){
                        return
                    }
                    this.move(i,i+1)
                }
                if (e.key == "ArrowRight"){
                    let i = this.nullIndex
                    if (!this.contain(i,i-1)){
                        return
                    }
                    this.move(i,i-1)
                }
            })
            $(window).on('resize',()=>{
                $('.container').height($('.container').width() * ($(".game-example").height() / $('.game-example').width()))
            })

            this.init()
        }
    });


</script>
</html>
